package cn.gov.cus.rmftquartz.common.ibmmq;

import cn.gov.cus.rmftquartz.common.utils.ExceptionHelper;
import com.google.common.base.Splitter;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.msg.client.wmq.compat.base.internal.MQC;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 消息接收器
 * @author wxming
 *
 */
public class MsgReceiver {

	//private static Config config = new Config("config.properties");
	private List<MQQueueManager> mqQueueManagers = Lists.newCopyOnWriteArrayList();
	private List<MQQueue> mqQueues = Lists.newCopyOnWriteArrayList();
	
	//public MsgReceiver(String queueNames, String channels) throws Exception{
	public MsgReceiver(String queueNames,String channels,String HostName,String Port,String CCSID,String UserID,String PassWD,String QM_NAME) throws Exception{

        /*MQEnvironment.hostname = config.getProperty("HostName");
        MQEnvironment.port = Integer.parseInt(config.getProperty("Port"));
        MQEnvironment.CCSID = Integer.parseInt(config.getProperty("CCSID"));
        MQEnvironment.userID = config.getProperty("UserID");
        MQEnvironment.password = config.getProperty("PassWD");*/
		
        MQEnvironment.hostname = HostName;
        MQEnvironment.port = Integer.parseInt(Port);
        MQEnvironment.CCSID = Integer.parseInt(CCSID);
        MQEnvironment.userID = UserID;
        MQEnvironment.password = PassWD;

        Table<Integer, String, String> tbNameChannel = getQueueManager(queueNames, channels);

        MQQueue mqQueue;
        //int openOptions = MQC.MQOO_BROWSE | MQC.MQOO_INPUT_AS_Q_DEF;
        int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | com.ibm.mq.MQC.MQOO_OUTPUT | com.ibm.mq.MQC.MQOO_INQUIRE;
        for (int i = 0; i < tbNameChannel.size(); i++) {
            for (Map.Entry<String, String> entry : tbNameChannel.row(i).entrySet()) {
                MQEnvironment.channel = entry.getValue();
                //MQQueueManager mqQueueManager = new MQQueueManager(config.getProperty("QM_NAME"));
                MQQueueManager mqQueueManager = new MQQueueManager(QM_NAME);
                mqQueue = mqQueueManager.accessQueue(entry.getKey(), openOptions);
                mqQueues.add(mqQueue);
                mqQueueManagers.add(mqQueueManager);
            }
        }

        if (mqQueues.size() == 0) {
            throw new Exception("mqQueues.size() ==0");
        }
    }

    static Table<Integer, String, String> getQueueManager(String queueNames, String channels) throws IOException {
        List<String> lstChannel = Splitter.on(',').omitEmptyStrings().trimResults().splitToList(channels);
        List<String> lstQueueName = Splitter.on(',').omitEmptyStrings().trimResults().splitToList(queueNames);

        Table<Integer, String, String> tbNameChannel = HashBasedTable.create();

        int nameSize = lstQueueName.size();
        int channelSize = lstChannel.size();
        int maxSize = channelSize > nameSize ? channelSize : nameSize;

        // 一对一,循环分组
        for (int i = 0; i < maxSize; i++) {
            tbNameChannel.put(i, lstQueueName.get(i % nameSize), lstChannel.get(i % channelSize));
        }

        return tbNameChannel;
    }

    static void doClose(List<MQQueueManager> mqQueueManagers, List<MQQueue> mqQueues) {
        try {
            for (MQQueue mqQueue : mqQueues) {
                if (mqQueue != null && mqQueue.isOpen()) {
                    mqQueue.close();
                }
            }
            for (MQQueueManager mqQueueManager : mqQueueManagers) {
                if (mqQueueManager != null && mqQueueManager.isOpen()) {
                    mqQueueManager.disconnect();
                }
            }

        } catch (MQException e) {
            System.out.println(ExceptionHelper.getExMsg(e));
        }
    }

    public List<MQQueue> getQueue() {
        return mqQueues;
    }

    public void close() {
        doClose(mqQueueManagers, mqQueues);
    }
}
